home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / TypeMatcher.C < prev    next >
C/C++ Source or Header  |  1992-06-23  |  4KB  |  206 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "TypeMatcher.h"
  6.  
  7. #include "Class.h"
  8. #include "String.h"
  9. #include "Data.h"
  10. #include "CLib.h"
  11. #include "OrdColl.h"
  12.  
  13. const char *cMagic= "@!OIO";
  14.  
  15. Symbol cDocCreatorUndef("__UNKNOWN__"),
  16.        cDocTypeUndef("UNDEF"),
  17.        cDocTypeAscii("ASCII"),
  18.        cDocTypeET("ET++OIO"),
  19.        cDocTypeCPlusPlus("C++"),
  20.        cDocTypeC("C"),
  21.        cDocTypeCHeader("CHEADER"),
  22.        cDocTypeDirectory("SYSDIRECTORY"),
  23.        cDocTypeSpecial("SYSSPECIAL");
  24.  
  25. //---- TypeMatcher -------------------------------------------------------------
  26.  
  27. NewMetaImpl(TypeMatcher,Object, (T(type), TS(extension), TS(tag), TB(ascii),
  28.                                 TP(matchers)));
  29.  
  30. OrdCollection *TypeMatcher::matchers;
  31. bool TypeMatcher::sorted;
  32.  
  33. void TypeMatcher::AddMatcher(TypeMatcher *ftm)
  34. {
  35.     if (ftm) {
  36.     if (matchers == 0)
  37.         matchers= new OrdCollection;
  38.     matchers->Add(ftm);
  39.     sorted= FALSE;
  40.     }
  41. }
  42.     
  43. TypeMatcher::TypeMatcher(Symbol t, char *ext, char *tg, bool ia, int prio)
  44. {
  45.     type= t;
  46.     creator= cDocCreatorUndef;
  47.     isCCode= FALSE;
  48.     isETFormat= FALSE;
  49.     extension= ext ? strsave(ext) : 0;  
  50.     tag= tg ? strsave(tg) : 0;
  51.     ascii= ia;
  52.     priority= prio;
  53.     AddMatcher(this);
  54. }
  55.  
  56. TypeMatcher::~TypeMatcher()
  57. {
  58.     SafeDelete(extension);
  59.     SafeDelete(tag);
  60.     if (matchers) {
  61.     matchers->RemovePtr(this);
  62.     if (matchers->Size() == 0)
  63.         SafeDelete(matchers);
  64.     }
  65. }
  66.  
  67. bool TypeMatcher::MatchPathName(char *pathname, int)
  68. {
  69.     char *s= strrchr(pathname, '.');
  70.     if (s) {
  71.     s++;
  72.     if (*s)
  73.         return MatchExtension(s);
  74.     }
  75.     return FALSE;
  76. }
  77.  
  78. bool TypeMatcher::MatchExtension(char *ext)
  79. {
  80.     return extension && (*ext == *extension) && (strcmp(ext, extension) == 0);
  81. }
  82.  
  83. bool TypeMatcher::MatchNameAndContents(char*, char *buf, int len)
  84. {
  85.     return MatchContents(buf, len);
  86. }
  87.  
  88. bool TypeMatcher::MatchContents(char *bp, int len)
  89. {
  90.     if (tag) {
  91.     int taglen= strlen(tag);
  92.     if (len >= taglen && *bp == *tag && strncmp(bp, tag, taglen) == 0)
  93.         return TRUE;
  94.     }
  95.     return FALSE;
  96. }
  97.  
  98. TypeMatcher *TypeMatcher::MatchByName(char *bp, int len)
  99. {
  100.     if (!sorted) {
  101.     matchers->Sort();
  102.     sorted= TRUE;
  103.     }
  104.  
  105.     Iter next(matchers);
  106.     TypeMatcher *m;
  107.  
  108.     while (m= (TypeMatcher*) next())
  109.     if (m->MatchPathName(bp, len))
  110.         return m;
  111.     return 0;
  112. }
  113.  
  114. const int cContentsSize= 1024;
  115.  
  116. TypeMatcher *TypeMatcher::MatchByContents(char *name)
  117. {
  118.     int namelen= strlen(name);
  119.     char buf[cContentsSize+1];
  120.     int fd= CLib::Open(name, 0);
  121.     if (fd < 0)
  122.     return 0;
  123.  
  124.     int l= CLib::Read(fd, buf, cContentsSize);
  125.     CLib::Close(fd);
  126.     if (l <= 0)
  127.     return 0;
  128.     buf[l]= '\0';
  129.  
  130.     if (!sorted) {
  131.     matchers->Sort();
  132.     sorted= TRUE;
  133.     }
  134.     Iter next(matchers);
  135.     TypeMatcher *m;
  136.  
  137.     while (m= (TypeMatcher*) next())
  138.     if (m->MatchNameAndContents(name, buf, l))
  139.         return m;
  140.     return 0;
  141. }
  142.  
  143. int TypeMatcher::Compare(Object *op)
  144. {
  145.     return priority - ((TypeMatcher*)op)->priority;
  146. }
  147.  
  148. //---- ETFileTypeMatcher -------------------------------------------------------
  149.  
  150. class ETFileTypeMatcher: public TypeMatcher {
  151. public:
  152.     MetaDef(ETFileTypeMatcher);
  153.     ETFileTypeMatcher() : TypeMatcher(cDocTypeET, "et", "@!OIO", TRUE)
  154.     { isETFormat= TRUE; }
  155.     bool MatchContents(char *buf, int);
  156. };
  157.  
  158. NewMetaImpl0(ETFileTypeMatcher,TypeMatcher);
  159.  
  160. static ETFileTypeMatcher et_matcher;
  161.  
  162. bool ETFileTypeMatcher::MatchContents(char *buf, int l)
  163. {
  164.     if (TypeMatcher::MatchContents(buf, l)) {
  165.     char ettype[100], crea[100];
  166.     if (sscanf(buf, "@!OIO %s %s", ettype, crea) == 2) {
  167.         type= Symbol(ettype);
  168.         creator= Symbol(crea);
  169.         return TRUE;
  170.     }
  171.     }
  172.     return FALSE;
  173. }
  174.  
  175. //---- CFileTypeMatcher --------------------------------------------------------
  176.  
  177. class CFileTypeMatcher: public TypeMatcher {
  178. public:
  179.     MetaDef(CFileTypeMatcher);
  180.     CFileTypeMatcher() : TypeMatcher(cDocTypeCPlusPlus, 0, 0, TRUE)
  181.     { isCCode= TRUE; }
  182.     bool MatchExtension(char *ext);
  183.     bool MatchNameAndContents(char *path, char *buf, int len);
  184. };
  185.  
  186. NewMetaImpl0(CFileTypeMatcher,TypeMatcher);
  187.  
  188. static CFileTypeMatcher cmatcher;
  189.  
  190. bool CFileTypeMatcher::MatchExtension(char *ext)
  191. {
  192.     if (ext[1] == '\0' && strchr("cChH", ext[0]))
  193.     return TRUE;
  194.     if (strcmp(ext, "cp") == 0)
  195.     return TRUE;
  196.     if (strcmp(ext, "cxx") == 0)
  197.     return TRUE;
  198.     return FALSE;
  199. }
  200.  
  201. bool CFileTypeMatcher::MatchNameAndContents(char *pathname, char*, int)
  202. {
  203.     return MatchPathName(pathname, strlen(pathname));
  204. }
  205.  
  206.